home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 039a / mawk.zip / CAST.C < prev    next >
C/C++ Source or Header  |  1991-04-07  |  7KB  |  355 lines

  1.  
  2. /********************************************
  3. cast.c
  4. copyright 1991, Michael D. Brennan
  5.  
  6. This is a source file for mawk, an implementation of
  7. the Awk programming language as defined in
  8. Aho, Kernighan and Weinberger, The AWK Programming Language,
  9. Addison-Wesley, 1988.
  10.  
  11. See the accompaning file, LIMITATIONS, for restrictions
  12. regarding modification and redistribution of this
  13. program in source or binary form.
  14. ********************************************/
  15.  
  16.  
  17. /*   $Log:    cast.c,v $
  18.  * Revision 2.1  91/04/08  08:22:44  brennan
  19.  * VERSION 0.97
  20.  * 
  21. */
  22.  
  23.  
  24. /*  cast.c  */
  25.  
  26. #include "mawk.h"
  27. #include "field.h"
  28. #include "memory.h"
  29. #include "scan.h"
  30. #include "repl.h"
  31. #include <string.h>
  32.  
  33. int pow2[NUM_CELL_TYPES] = {1,2,4,8,16,32,64,128,256,512} ;
  34.  
  35. void cast1_to_d( cp )
  36.   register CELL *cp ;
  37. {
  38.   switch( cp->type )
  39.   { case C_NOINIT :  cp->dval = 0.0 ; break ;
  40.  
  41.     case C_DOUBLE :  return ;
  42.  
  43.     case C_MBSTRN :
  44.     case C_STRING :  
  45.           { register STRING *s = (STRING *) cp->ptr  ;
  46.  
  47. #if FPE_TRAPS  /* look for overflow error */
  48.             errno = 0 ;
  49.             cp->dval = strtod(s->str,(char **)0) ;
  50.             if ( errno && cp->dval != 0.0 ) /* ignore underflow */
  51.                 rt_error("overflow converting %s to double", s) ;
  52. #else
  53.             cp->dval = strtod(s->str,(char **)0) ;
  54. #endif
  55.             free_STRING(s) ;
  56.           }
  57.             break ;
  58.  
  59.     case C_STRNUM :  
  60.       /* don't need to convert, but do need to free the STRING part */
  61.             free_STRING( string(cp) ) ;
  62.             break ;
  63.  
  64.  
  65.     default :
  66.             bozo("cast on bad type") ;
  67.   }
  68.   cp->type = C_DOUBLE ;
  69. }
  70.  
  71. void cast2_to_d( cp )
  72.   register CELL *cp ;
  73. { register STRING *s ;
  74.  
  75.   switch( cp->type )
  76.   { case C_NOINIT :  cp->dval = 0.0 ; break ;
  77.  
  78.     case C_DOUBLE :  goto two ;
  79.     case C_STRNUM :  
  80.             free_STRING( string(cp) ) ;
  81.             break ;
  82.  
  83.     case C_MBSTRN :
  84.     case C_STRING :  
  85.             s = (STRING *) cp->ptr ;
  86.  
  87. #if FPE_TRAPS  /* look for overflow error */
  88.             errno = 0 ;
  89.             cp->dval = strtod(s->str,(char **)0) ;
  90.             if ( errno && cp->dval != 0.0 ) /* ignore underflow */
  91.                 rt_error("overflow converting %s to double", s) ;
  92. #else
  93.             cp->dval = strtod(s->str,(char **)0) ;
  94. #endif
  95.             free_STRING(s) ;
  96.             break ;
  97.  
  98.     default :
  99.             bozo("cast on bad type") ;
  100.   }
  101.   cp->type = C_DOUBLE ;
  102.  
  103. two:   cp++ ;
  104.   switch( cp->type )
  105.   { case C_NOINIT :  cp->dval = 0.0 ; break ;
  106.  
  107.     case C_DOUBLE :  return ;
  108.     case C_STRNUM :  
  109.             free_STRING( string(cp) ) ;
  110.             break ;
  111.  
  112.     case C_MBSTRN :
  113.     case C_STRING :  
  114.             s = (STRING *) cp->ptr ;
  115.  
  116. #if FPE_TRAPS  /* look for overflow error */
  117.             errno = 0 ;
  118.             cp->dval = strtod(s->str,(char **)0) ;
  119.             if ( errno && cp->dval != 0.0 ) /* ignore underflow */
  120.                 rt_error("overflow converting %s to double", s) ;
  121. #else
  122.             cp->dval = strtod(s->str,(char **)0) ;
  123. #endif
  124.             free_STRING(s) ;
  125.             break ;
  126.  
  127.     default :
  128.             bozo("cast on bad type") ;
  129.   }
  130.   cp->type = C_DOUBLE ;
  131. }
  132.  
  133. void cast1_to_s( cp )
  134.   register CELL *cp ;
  135.   switch( cp->type )
  136.   { case C_NOINIT :  
  137.         null_str.ref_cnt++ ;
  138.         cp->ptr = (PTR) &null_str ;
  139.         break ;
  140.  
  141.     case C_DOUBLE  :
  142.         (void) sprintf(temp_buff.string_buff ,
  143.             string(field+OFMT)->str, cp->dval) ;
  144.  
  145.         cp->ptr = (PTR) new_STRING(temp_buff.string_buff) ;
  146.         break ;
  147.  
  148.     case C_STRING :  return ;
  149.  
  150.     case C_MBSTRN :
  151.     case C_STRNUM :  break ;
  152.  
  153.     default :  bozo("bad type on cast") ;
  154.   }
  155.   cp->type = C_STRING ;
  156. }
  157.  
  158. void cast2_to_s( cp )
  159.   register CELL *cp ;
  160.  
  161.   switch( cp->type )
  162.   { case C_NOINIT : 
  163.         null_str.ref_cnt++ ;
  164.         cp->ptr = (PTR) &null_str ;
  165.         break ;
  166.  
  167.     case C_DOUBLE  :
  168.         (void) sprintf(temp_buff.string_buff,
  169.             string(field+OFMT)->str, cp->dval ) ;
  170.  
  171.         cp->ptr = (PTR) new_STRING(temp_buff.string_buff) ;
  172.         break ;
  173.  
  174.     case C_STRING :  goto two ;
  175.  
  176.     case C_MBSTRN :
  177.     case C_STRNUM :  break ;
  178.  
  179.     default :  bozo("bad type on cast") ;
  180.   }
  181.   cp->type = C_STRING ;
  182.  
  183. two:
  184.   cp++ ;
  185.  
  186.   switch( cp->type )
  187.   { case C_NOINIT :  
  188.         null_str.ref_cnt++ ; 
  189.         cp->ptr = (PTR) &null_str ;
  190.         break ;
  191.  
  192.     case C_DOUBLE  :
  193.         (void) sprintf(temp_buff.string_buff,
  194.             string(field+OFMT)->str, cp->dval) ;
  195.  
  196.         cp->ptr = (PTR) new_STRING(temp_buff.string_buff) ;
  197.         break ;
  198.  
  199.     case C_STRING :  return ;
  200.  
  201.     case C_MBSTRN :
  202.     case C_STRNUM :  break ;
  203.  
  204.     default :  bozo("bad type on cast") ;
  205.   }
  206.   cp->type = C_STRING ;
  207. }
  208.  
  209. void  cast_to_RE( cp )
  210.   register CELL *cp ;
  211. { register PTR p ;
  212.  
  213.   if ( cp->type < C_STRING )  cast1_to_s(cp) ;
  214.  
  215.   p = re_compile( string(cp) ) ;
  216.   free_STRING( string(cp) ) ;
  217.   cp->type = C_RE ;
  218.   cp->ptr = p ;
  219.  
  220. }
  221.  
  222. void  cast_for_split(cp)
  223.   register CELL *cp ;
  224. {
  225.   static char meta[] = "^$.*+?|[]()" ;
  226.   static char xbuff[] = "\\X" ;
  227.   int c ;
  228.   unsigned len ;
  229.     
  230.   if ( cp->type < C_STRING )  cast1_to_s(cp) ;
  231.  
  232.   if ( (len = string(cp)->len) == 1 )
  233.   {
  234.         if ( (c = string(cp)->str[0]) == ' ' )
  235.         { free_STRING(string(cp)) ;
  236.           cp->type = C_SPACE ; 
  237.           return ; 
  238.         }
  239.         else
  240.         if ( strchr(meta, c) )
  241.         { xbuff[1] = c ;
  242.           free_STRING(string(cp)) ;
  243.           cp->ptr = (PTR) new_STRING(xbuff) ;
  244.         }
  245.   }
  246.   else
  247.   if ( len == 0 ) 
  248.   { free_STRING(string(cp)) ;
  249.     cp->type = C_SNULL ; 
  250.     return ; 
  251.   }
  252.  
  253.   cast_to_RE(cp) ;
  254. }
  255.  
  256. /* input: cp-> a CELL of type C_MBSTRN (maybe strnum)
  257.    test it -- casting it to the appropriate type
  258.    which is C_STRING or C_STRNUM
  259. */
  260.  
  261. void check_strnum( cp )
  262.   CELL *cp ;
  263. { char *test ;
  264.   register unsigned char *s , *q ;
  265.  
  266.   cp->type = C_STRING ; /* assume not C_STRNUM */
  267.   s = (unsigned char *) string(cp)->str ;
  268.   q = s + string(cp)->len ;
  269.   while ( scan_code[*s] == SC_SPACE )  s++ ;
  270.   if ( s == q )  return ;
  271.  
  272.   while ( scan_code[ q[-1] ] == SC_SPACE )  q-- ;
  273.   if ( scan_code[ q[-1] ] != SC_DIGIT &&
  274.        q[-1] != '.' )   return ;
  275.  
  276.   switch ( scan_code[*s] )
  277.   {
  278.     case SC_DIGIT :
  279.     case SC_PLUS  :
  280.     case SC_MINUS :
  281.     case SC_DOT   :
  282.  
  283. #if FPE_TRAPS
  284.              errno = 0 ;
  285.              cp->dval  = strtod((char *)s, &test) ;
  286.              if ( errno && cp->dval != 0.0 )
  287.                 rt_error(
  288.                 "overflow converting %s to double" , s) ;
  289. #else
  290.              cp->dval = strtod(s, &test) ;
  291. #endif
  292.  
  293.              if ((char *) q == test )  cp->type = C_STRNUM ;
  294.   }
  295. }
  296.  
  297. /* cast a CELL to a replacement cell */
  298.  
  299. void cast_to_REPL( cp )
  300.   register CELL *cp ;
  301. { register STRING *sval ;
  302.  
  303.   if ( cp->type < C_STRING )  cast1_to_s(cp) ;
  304.   sval = (STRING *) cp->ptr ;
  305.  
  306.   (void) cellcpy(cp, repl_compile(sval)) ;
  307.   free_STRING(sval) ;
  308. }
  309.  
  310.  
  311. #if   NO_STRTOD
  312.  
  313. static char d_str[] =
  314. "^[ \t]*[-+]?([0-9]+\\.?|\\.[0-9])[0-9]*([eE][-+]?[0-9]+)?" ;
  315.  
  316. static PTR d_ptr ;
  317.  
  318. void strtod_init()
  319. { STRING *sval = new_STRING(d_str) ;
  320.  
  321.   d_ptr = re_compile(sval) ;
  322.   free_STRING(sval) ;
  323. }
  324.  
  325. double strtod( s, endptr)
  326.   char *s , **endptr ;
  327. { double atof() ;
  328.  
  329.   if ( endptr )
  330.   { unsigned len ;
  331.  
  332.     (void) REmatch(s, d_ptr, &len) ;
  333.     *endptr = s + len ;
  334.   }
  335.   return  atof(s) ;
  336. }
  337. #endif  /* NO_STRTOD */
  338.  
  339. #if   NO_FMOD
  340.  
  341. double  fmod(x, y)
  342.   double x, y ;
  343. { double modf() ;
  344.   double ipart ;
  345.  
  346.   return modf(x/y, &ipart) * y ;
  347. }
  348.  
  349. #endif  /* NO_FMOD */
  350.  
  351.  
  352.  
  353.